package com.ming.common.beetl.util;

import com.ming.common.beetl.cache.CacheSqlExecUtil;
import com.ming.common.beetl.cache.CacheSqlManagerUtil;
import com.ming.common.beetl.entity.BaseEntity;
import org.beetl.sql.core.SQLManager;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SQLExecUtil {

    private volatile static SQLExecUtil instance;
    private SQLExecUtil(){ }
    public  static SQLExecUtil NEW() {
        if (instance == null){
            synchronized (SQLExecUtil.class){
                if (instance == null){
                    instance = new SQLExecUtil();
                }
            }
        }
        return instance;
    }

    private SQLManager sqlManager;

    private String sqlId;

    private Object[] params;

    private Object result;


    public SQLExecUtil sqlManager(SQLManager sqlManager){
        this.sqlManager = sqlManager;
        return this;
    }

    public SQLExecUtil sqlId(String sqlId){
        this.sqlId = sqlId;
        return this;
    }

    public SQLExecUtil params(Object... params){
        this.params = params;
        return this;
    }

    public SQLExecUtil exec(){
        BaseEntity baseEntity = CacheSqlExecUtil.getCache(this.sqlId);
        return exec(baseEntity);
    }

    public SQLExecUtil exec(BaseEntity baseEntity){
        String sqlManagerId = baseEntity.getStrValue(StrUtil.snakeToCamel("sql_manager_id"));
        String tableName = baseEntity.getStrValue(StrUtil.snakeToCamel("table_name"));
        String sqlType = baseEntity.getStrValue(StrUtil.snakeToCamel("sql_type"));
        SQLManager sqlManager = null;
        if(StrUtil.isNotEmpty(sqlManagerId)){
            sqlManager = CacheSqlManagerUtil.getCache(sqlManagerId, SQLManager.class);
        }else{
            sqlManager = this.sqlManager;
        }
        Map<String,Object> data = new HashMap<>();
        switch (sqlType.toLowerCase()){
            case "select": this.result = QueryUtil.select(sqlManager, baseEntity, this.params);break;
            case "insert": this.result = QueryUtil.insertSelective(sqlManager,tableName,data);break;
            case "update": this.result = QueryUtil.updateSelectiveById(sqlManager,tableName,data,"id");break;
            case "delete": this.result = QueryUtil.deleteById(sqlManager,tableName,data,"id");break;
            default: break;
        }
        return this;
    }

    public Object result(){
        return this.result;
    }

    public BaseEntity single(){
        List<? extends BaseEntity> entities = (List<? extends BaseEntity>) this.result;
        return entities.stream().findFirst().orElse(null);
    }

    public void list(){

    }

    /*public List<? extends BaseEntity> selectAll(){
        return QueryUtil.selectAll(sqlManager,tableName);
    }

    public Map<String, ? extends BaseEntity> selectAllToStrMap(Function<? super BaseEntity, ? extends String> keyMapper, Function<? super BaseEntity, ? extends BaseEntity> valueMapper) {
        List<? extends BaseEntity> dataSourceList = selectAll();
        return dataSourceList.stream().collect(Collectors.toMap(keyMapper, valueMapper));
    }

    public Map<Long, ? extends BaseEntity> selectAllToLongMap(Function<? super BaseEntity, ? extends Long> keyMapper, Function<? super BaseEntity, ? extends BaseEntity> valueMapper) {
        List<? extends BaseEntity> dataSourceList = selectAll();
        return dataSourceList.stream().collect(Collectors.toMap(keyMapper, valueMapper));
    }

    public int insert(Map<String,Object> data) {
        return QueryUtil.insertSelective(sqlManager,tableName,data);
    }

    public int updateById(Map<String,Object> data) {
        return QueryUtil.updateSelectiveById(sqlManager,tableName,data,primaryKey);
    }

    public int deleteById(Map<String,Object> data) {
        return QueryUtil.deleteById(sqlManager,tableName,data,primaryKey);
    }*/
}
